package dp.mobile.entity.generator;

import javax.microedition.khronos.opengles.GL10;

import android.provider.ContactsContract.Contacts.Data;
import android.util.Log;

import dp.mobile.entity.Entity;
import dp.mobile.entity.generator.GeneratorFactory.GeneratorAttribute;
import dp.mobile.entity.saveable.SaveableGenerator;
import dp.mobile.entity.tower.Tower;
import dp.mobile.game.Player;
import dp.mobile.glwrapper.GLTexture;
import dp.mobile.glwrapper.GameRenderer;
import dp.mobile.system.Utilities;

public class Generator extends Entity {
	private static final String TAG = "Generator";
	
	protected Generator() {
		mName				= "Generator";
		mData 				= null;
		mTileX				= 0;
		mTileY				= 0;
		mShowRange			= false;
		mActive				= false;
		mProgressTime 		= 0;
		mCurrentTime 		= 0;
		mRegenTime			= 0;
		mTransferPower		= 0;
		mTransferRange		= 0;
		mTransferVoltage	= 0;
		mTargetGenerator 	= null;
	}
	
	public Generator(GeneratorData data, Player player, int x, int y, long startTime, boolean delay) {
		this();
		mPlayer = player;
		mTileX 	= x;
		mTileY 	= y;
		mData	= data;
		mActive = true;
		//upgrade(data, startTime, delay);
	}
	
	public boolean upgrade(GeneratorData newData, long startTime, boolean delay, boolean force) {
		if (isInProgress(startTime) && !force) return false;
		boolean canBuy = true;
		int[] cost = new int[] {0, 0, 0};
		int upgradeTime = 0;
		
		if (mPlayer.getElectricity() < newData.getBuildCost()) canBuy = false;
		// kalau bukan generator basic, maka renggut lah komponennya
		if (mData != null) {
			for (int i = 0; i < 3; ++i) {
				cost[i] += newData.getPowerAttribute().getWorth(i) - mData.getPowerAttribute().getWorth(i);
				cost[i] += newData.getRangeAttribute().getWorth(i) - mData.getRangeAttribute().getWorth(i);
				cost[i] += newData.getVoltageAttribute().getWorth(i) - mData.getVoltageAttribute().getWorth(i);
				
				if (cost[i] > mPlayer.getComponents(i)) {
					canBuy = false;
					break;
				}
			}
		}
		
		if (!canBuy && !force) return false;
		
		mPlayer.addElectricity(-newData.getBuildCost());
		for (int i = 0; i < 3; ++i)
			mPlayer.addComponent(i, -cost[i]);
		if (delay) {
			// kalau generator basic, tambahin semua elemennya!
			if ((newData.getPowerAttribute().getLevel() == 1) &&
					(newData.getRangeAttribute().getLevel() == 1) &&
					(newData.getVoltageAttribute().getLevel() == 1)) {
				upgradeTime += newData.getPowerAttribute().getUpgradeTime();
				upgradeTime += newData.getRangeAttribute().getUpgradeTime();
				upgradeTime += newData.getVoltageAttribute().getUpgradeTime();
			} else {
				if (mData.getPowerAttribute().getLevel() < newData.getPowerAttribute().getLevel())
					upgradeTime += newData.getPowerAttribute().getUpgradeTime();
				if (mData.getRangeAttribute().getLevel() < newData.getRangeAttribute().getLevel())
					upgradeTime += newData.getRangeAttribute().getUpgradeTime();
				if (mData.getVoltageAttribute().getLevel() < newData.getVoltageAttribute().getLevel())
					upgradeTime += newData.getVoltageAttribute().getUpgradeTime();
			}
		}
		
		mProgressTime	= upgradeTime;
		mStartProgress	= startTime;
		mCurrentTime 	= startTime;
		mData = newData;
		mRegenTime = startTime + newData.getRegenPeriode();
		
		return true;
	}
	
	public boolean transferPower(long startTime, Generator targetGenerator) {
		if (isInProgress(startTime)) return false;
		mCurrentTime 		= startTime;
		mStartProgress		= startTime;
		mProgressTime		= mData.getTransferTime();
		mTargetGenerator	= targetGenerator;
		
		return true;
	}
	
	public boolean dismantle(long startTime , boolean force) {
		if (mPlayer.getElectricity() < mData.getDismantleCost() && !force) return false;
		if (isInProgress(startTime) && !force) return false;
		
		mPlayer.addElectricity(-mData.getDismantleCost());
		mCurrentTime 	= startTime;
		mStartProgress 	= startTime;
		mProgressTime 	= mData.getDismantleTime();
		
		return true;
	}
	
	public boolean isInProgress(long time) {
		return time - mStartProgress <= mProgressTime;
	}
	
	public boolean haveJustGenerateElectricity() {
		return mHaveJustGenerate;
	}
	
	public void setRangeShowing(boolean showRange) {
		mShowRange = showRange;
	}
	
	public GeneratorData getData() {
		return mData;
	}
	
	public boolean inRange(Entity other) {
		final float dX = other.getX() - getX();
		final float dY = other.getY() - getY();
		final float range = mData.getRange();
		
		return dX * dX + dY * dY < range * range;
	}
	
	public void update(long time) {
		if (!mActive) return;
		mCurrentTime += time;
		mHaveJustGenerate = false;
		
		if (!isInProgress(mCurrentTime)){
			if (mCurrentTime >= mRegenTime) {
				mHaveJustGenerate = true;
				mPlayer.addElectricity(mData.getRegen());
				mRegenTime = mCurrentTime + mData.getRegenPeriode();
			}
			// TODO : pass electricity and revert electricity
		}
	}
	
	public float getDamageBonus() {
		if (isInProgress(mCurrentTime))
			return 0;
		return mData.getDamageBonus();
	}
	
	public float getSpeedBonus() {
		if (isInProgress(mCurrentTime))
			return 0;
		return mData.getSpeedBonus();
	}
	
	@Override
	public void draw(GL10 gl) {
		if (mData.getImage() == null) return;
		
		//Calculate draw position
		int X = (mTileX * Utilities.TILE_WIDTH);
		int Y = (mTileY * Utilities.TILE_HEIGHT);
		
		final GLTexture texture = mData.getImage();
		GameRenderer.instance().draw(gl, texture, GameRenderer.FLIPPED_TEXTURE, X, Y, Utilities.TILE_WIDTH , Utilities.TILE_HEIGHT, Utilities.TOWER_DEPTH);
		
		// draw progress bar
		if (isInProgress(mCurrentTime)) {
			final long progress = mCurrentTime - mStartProgress;
			GameRenderer.instance().draw(gl, GameRenderer.instance().getProgressBarImage(), X, Y - 6, (int)((float)progress / (float)mProgressTime * (float)(Utilities.TILE_WIDTH)), 4, Utilities.TOWER_DEPTH);
		}
		
		//Draw range
		if (mShowRange) {
			int range = (int)mData.getRange();
			final int rangeX = X + Utilities.TILE_WIDTH / 2 - range;
			final int rangeY = Y + Utilities.TILE_HEIGHT / 2 - range;
			range = range * 2;
			GameRenderer.instance().draw(gl, GameRenderer.instance().getRangeImage(), rangeX, rangeY, range, range, Utilities.RANGE_DEPTH);
		}
	}
	
	public SaveableGenerator createSaveable() {
		SaveableGenerator retval = new SaveableGenerator();
		
		retval.mId = getID();
		retval.mPowerLevel = getData().getPowerLevel();
		retval.mRangeLevel = getData().getRangeLevel();
		retval.mVoltageLevel = getData().getVoltageLevel();
		retval.mTileX = mTileX;
		retval.mTileY = mTileY;
		
		return retval;
	}
	
	protected GeneratorData mData;
	protected boolean		mShowRange;
	
	protected int mTransferPower, mTransferRange, mTransferVoltage;
	protected Generator mTargetGenerator;
	
	// delaying stuff
	private long mStartProgress;
	private long mCurrentTime;
	private long mRegenTime;
	private long mProgressTime;
	private boolean mHaveJustGenerate;
	private boolean mActive;
}
